package com.domainlanguage.time;

import org.hibernate.type.ImmutableType;
import org.hibernate.HibernateException;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.PreparedStatement;
import java.sql.Types;
import java.lang.reflect.Field;

/**
 * Hibernate user type for {@link com.domainlanguage.time.TimeUnit}.
 *
 * Backed by {@link java.sql.Types.VARCHAR}.
 *
 */
public class TimeUnitType extends ImmutableType {
    @Override
    public Object get(final ResultSet rs, final String name) throws HibernateException, SQLException {
        final String unitName = rs.getString(name);
        if (unitName == null) {
            return null;
        }

        return readFieldNamed(unitName);
    }

    @Override
    public void set(final PreparedStatement st, final Object value, final int index) throws HibernateException, SQLException {
        st.setString(index, value.toString());
    }

    @Override
    public int sqlType() {
        return Types.VARCHAR;
    }

    @Override
    public String toString(final Object value) throws HibernateException {
        return value.toString();
    }

    @Override
    public Object fromStringValue(final String xml) throws HibernateException {
        return readFieldNamed(xml);
    }

    private Object readFieldNamed(final String xml) {
        try {
            final Field field = TimeUnit.class.getField(xml);
            field.setAccessible(true);
            return field.get(null);
        } catch (IllegalAccessException e) {
            throw new HibernateException(e);
        } catch (NoSuchFieldException e) {
            throw new HibernateException(e);
        }
    }


    @Override
    public Class getReturnedClass() {
        return TimeUnit.class;
    }

    @Override
    public String getName() {
        return "timeUnit";
    }

}
